home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Video Toaster 4.2
/
Video Toaster v4.2.iso
/
arexx
/
modeler
/
pointxform.lwm
< prev
next >
Wrap
Text File
|
1993-12-13
|
5KB
|
189 lines
/* CMD: Transform Points
* Transform points algorithmically: Swirl,
* By Arnie Cachelin © 1992, 1993 NewTek Inc.
*/
libadd = addlib("LWModelerARexx.port",0)
signal on error
signal on syntax
call addlib "rexxsupport.library", 0, -30, 0
req=0
xf=0
coords.1='z,y,x'
coords.2='x,z,y'
coords.3='x,y,z'
MATHLIB="rexxmathlib.library"
IF POS(MATHLIB , SHOW('L')) = 0 THEN
IF ~ADDLIB(MATHLIB , 0 , -30 , 0) THEN DO
call notify(1,"!Can't find "MATHLIB)
exit
END
ax=3
rate=90
cx=0
cy=0
cz=0
rmax=1
from=1
version = 'XForm v1.0'
filnam = 'ENV:XForm.state'
if (exists(filnam)) then do
if (~open(state, filnam, 'R')) then break
if (readln(state) ~= version) then break
parse value readln(state) with ax rate cx cy cz rmax from .
call close state
end
call req_begin "Point Transformations"
id_txt = req_addcontrol("Rotate points", 'T',"inside Effect Radius based on")
id_txt = req_addcontrol("their radial", 'T',"positions")
id_Axis = req_addcontrol("Axis", 'CH','X Y Z')
id_cen = req_addcontrol("Center", 'v', 1)
id_rate = req_addcontrol("Rotation Amount (°/m) ", 'n', 0)
id_rad = req_addcontrol("Effect Radius", 'n', 0)
id_from = req_addcontrol("Turn From", 'CH','Center Edge Middle')
xform.1= 'a=a+(rmax-r)*rate' /* Swirl stronger at center */
xform.2= 'a=a+r*rate' /* Swirl stronger at edge */
xform.3= 'a=a+rmax-2*abs(rmax/2-r)*rate' /* Swirl strongest at rmax/2 */
call req_setval id_Axis, ax
call req_setval id_rate, rate
call req_setval id_cen, cx cy cz, 0.0
call req_setval id_from, from
call req_setval id_rad, rmax, 1.0
if (~req_post()) then do
call req_end
exit
end
ax= req_getval(id_Axis)
rate=req_getval(id_rate)
parse value req_getval(id_cen) with cx cy cz .
rmax =req_getval(id_rad)
from =req_getval(id_from)
call req_end
if (open(state, filnam, 'W')) then do
call writeln state, version
call writeln state, ax rate cx cy cz rmax from
call close state
end
Pi=3.14159265358
DegreesPerRadian= 180/pi
/* Transform loop */
t=time('e')
n = xfrm_begin()
call meter_begin n, 'Transforming 'n' Points'
do i = 1 to n
parse value xfrm_getpos(i) with dx dy dz .
x = dx - cx
y = dy - cy
z = dz - cz
interpret 'r=Cyl_R('coords.ax')'
interpret 'a=Cyl_Theta('coords.ax')'
interpret 'My_Z='translate(ax,"XYZ","123")
/* say '#'i ax coords.ax x y z */
/* say r*1 rmax a'°' My_Z */
if r>rmax then iterate
interpret xform.from
x=Cyl_X(r,a,My_Z)+cx
y=Cyl_Y(r,a,My_Z)+cy
z=My_Z+cz
pos=translate(coords.ax," ",",")
/* say i '--->' x y z a'°' */
cmd= 'call xfrm_setpos 'i','pos
interpret cmd
call meter_step
end
call meter_end
call xfrm_end
t=time('e')-t
if n>100 then call notify(1,'!Whew, I just transformed 'n' points','!in only 't' seconds.')
if (libadd) then call remlib("LWModelerARexx.port")
exit
syntax:
error:
call end_all
t=Notify(1,'!Rexx Script Error','@'ErrorText(rc),'Line 'SIGL)
if (libadd) then call remlib("LWModelerARexx.port")
exit
/*
The following functions convert between 3D cartesian coordinates (X,Y,Z)
and either cylindrical coordinates (R,Theta,Z) or Spherical
coordinates (R,Theta,Phi). The Cylindrical coordinate conversions don't
take Z inputs, since Z is the same in both cylindical and cartesian systems.
To go between spherical and cylindrical, use cartesian... or write your own.
p.s. I lied... see Cyl_Z(), z args are ok now too.
*/
/* Return R in Cylindrical coordinate system */
Cyl_R: PROCEDURE
arg xf, yf, zf
return sqrt(xf*xf+yf*yf)
Cyl_Z: PROCEDURE
arg xf, yf, zf
return zf
/* Return Theta in Cylindrical coordinate system */
Cyl_Theta: PROCEDURE EXPOSE DegreesPerRadian Pi
arg x, y, z
if x=0 then t=sign(y)*90
else t=DegreesPerRadian*atan(y/x)
if x<0 then t=t + 180 /* atan() doesn't know which quadrant you're in */
if t<0 then t=t + 360 /* atan() returns -180 to 180, I like 0 to 360 */
return t
/* Return Cartesian X from Cylindrical coordinate system */
Cyl_X: PROCEDURE EXPOSE DegreesPerRadian
arg R, Theta, Z
return R*cos(Theta/DegreesPerRadian)
/* Return Cartesian Y from Cylindrical coordinate system */
Cyl_Y: PROCEDURE EXPOSE DegreesPerRadian
arg R, Theta, Z
return R*sin(Theta/DegreesPerRadian)
/* Return R in Spherical coordinate system */
Sphere_R: PROCEDURE
arg x, y, z
return sqrt(x*x+y*y+z*z)
/* Return Theta in Spherical coordinate system */
Sphere_Theta: PROCEDURE EXPOSE DegreesPerRadian Pi
arg x, y, z
if x=0 then t=sign(y)*90
else t=DegreesPerRadian*atan(y/x)
if x<0 then t=t + 180 /* atan() doesn't know which quadrant you're in */
if t<0 then t=t + 360 /* atan() returns -180 to 180, I like 0 to 360 */
return t
/* Return Phi in Spherical coordinate system */
Sphere_Phi: PROCEDURE EXPOSE DegreesPerRadian Pi
arg x, y, z
if z=0 then return 90
else return DegreesPerRadian*atan(sqrt(x*x+y*y)/z)
/* Return Cartesian X from Spherical coordinate system */
Sphere_X: PROCEDURE EXPOSE DegreesPerRadian
arg R, Theta, Phi
return R*sin(abs(Phi)/DegreesPerRadian)*cos(Theta/DegreesPerRadian)
/* Return Cartesian Y from Spherical coordinate system */
Sphere_Y: PROCEDURE EXPOSE DegreesPerRadian
arg R, Theta, Phi
return R*sin(abs(Phi)/DegreesPerRadian)*sin(Theta/DegreesPerRadian)
/* Return Cartesian Z from Spherical coordinate system */
Sphere_Z: PROCEDURE EXPOSE DegreesPerRadian
arg R, Theta, Phi
return sign(Phi)*R*cos(Phi/DegreesPerRadian)